{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e1d75774",
   "metadata": {},
   "source": [
    "### 1.类的基本定义形式\n",
    "\n",
    "Python中的变量、列表、字典等其实都是对象。\n",
    "\n",
    "而类声明如下：\n",
    "\n",
    "class class_name:\n",
    "\n",
    "    Functions"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a5dc44dc",
   "metadata": {},
   "source": [
    "如果只是定义一个类，里面没有功能，那么冒号后面必须要有一个pass说明"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "f5222ee4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "__main__.FirstClass"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class FirstClass:#声明了一个最简单的类对象\n",
    "    pass\n",
    "\n",
    "#class1就等同于FirstClass，也称是这个类的实例\n",
    "class1=FirstClass()\n",
    "type(class1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "43efd207",
   "metadata": {},
   "source": [
    "而向这个类里面添加一些功能，称为该类的方法\n",
    "\n",
    "可能这个理解并非很正确，一个类里面包含的方法可以对它进行操作，就像列表里的各种函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "080fac8b",
   "metadata": {},
   "outputs": [],
   "source": [
    "class firstclass:\n",
    "    '''My first class'''#直接添加了说明文件，用help就可以打开\n",
    "    class_const=10\n",
    "    def __init__(self,name,symbol):\n",
    "        self.n=name\n",
    "        self.s=symbol"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d2e5859a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['__class__',\n",
       " '__delattr__',\n",
       " '__dict__',\n",
       " '__dir__',\n",
       " '__doc__',\n",
       " '__eq__',\n",
       " '__format__',\n",
       " '__ge__',\n",
       " '__getattribute__',\n",
       " '__gt__',\n",
       " '__hash__',\n",
       " '__init__',\n",
       " '__init_subclass__',\n",
       " '__le__',\n",
       " '__lt__',\n",
       " '__module__',\n",
       " '__ne__',\n",
       " '__new__',\n",
       " '__reduce__',\n",
       " '__reduce_ex__',\n",
       " '__repr__',\n",
       " '__setattr__',\n",
       " '__sizeof__',\n",
       " '__str__',\n",
       " '__subclasshook__',\n",
       " '__weakref__',\n",
       " 'class_const']"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dir(firstclass)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "668da008",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['__class__',\n",
       " '__delattr__',\n",
       " '__dict__',\n",
       " '__dir__',\n",
       " '__doc__',\n",
       " '__eq__',\n",
       " '__format__',\n",
       " '__ge__',\n",
       " '__getattribute__',\n",
       " '__gt__',\n",
       " '__hash__',\n",
       " '__init__',\n",
       " '__init_subclass__',\n",
       " '__le__',\n",
       " '__lt__',\n",
       " '__module__',\n",
       " '__ne__',\n",
       " '__new__',\n",
       " '__reduce__',\n",
       " '__reduce_ex__',\n",
       " '__repr__',\n",
       " '__setattr__',\n",
       " '__sizeof__',\n",
       " '__str__',\n",
       " '__subclasshook__',\n",
       " '__weakref__',\n",
       " 'class_const',\n",
       " 'n',\n",
       " 's']"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "eg1=firstclass(\"one\",1)\n",
    "eg2=firstclass(\"two\",2)\n",
    "dir(eg1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b96c5976",
   "metadata": {},
   "source": [
    "**在这里对类的定义做出几点解释**\n",
    "\n",
    "* 头两行是用户自行定义的说明文件__doc__和变量class_const，使用dir()可以查看\n",
    "* 在使用dir查看时，除了自身定义的东西之外，还可以看到很多默认包含的\n",
    "\n",
    "\n",
    "* 很多类都会有 __init__ 函数，称魔术方法，一般必须进行定义调用\n",
    "* eg1和eg2相对比firstclass，属性里多了'n'和's'\n",
    "* **def里面定义的self其实就是firstclass本身，这个可以更改，但一般用self**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "196fd02b",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "one 1\n",
      "two 2\n"
     ]
    }
   ],
   "source": [
    "print(eg1.n,eg1.s)\n",
    "print(eg2.n,eg2.s)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba4f6ee5",
   "metadata": {},
   "source": [
    "**就像我们前面看到的全局变量和局部变量一样，即使类也有自己的变量类型。**\n",
    "\n",
    "**类属性:**在方法外部定义的属性，适用于所有实例。如class_const\n",
    "\n",
    "**实例属性:**在方法内部定义的属性，只适用于该方法，并且对每个实例都是唯一的。如.n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dc133074",
   "metadata": {},
   "source": [
    "**init是一个必须定义功能的初始函数，除此之外还可以继续定义其他方法**\n",
    "\n",
    "注意，这里后面的个函数都用到了init中的self.symbol"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "1e3df55a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'type'>\n"
     ]
    }
   ],
   "source": [
    "class FirstClass:\n",
    "    def __init__(self,name,symbol):\n",
    "        self.name = name\n",
    "        self.symbol = symbol\n",
    "    def square(self):\n",
    "        return self.symbol * self.symbol\n",
    "    def cube(self):\n",
    "        return self.symbol * self.symbol * self.symbol\n",
    "    def multiply(self, x):\n",
    "        return self.symbol * x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "882a9992",
   "metadata": {},
   "source": [
    "一般是将类赋给eg5后调用函数，当然也可以直接在FirstClass调用输出"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "dab3557c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "125\n",
      "10\n"
     ]
    }
   ],
   "source": [
    "eg5=FirstClass('Five',5)\n",
    "print(eg5.cube())\n",
    "print(FirstClass.multiply(eg5,2))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "923bcbfb",
   "metadata": {},
   "source": [
    "### 2.继承\n",
    "\n",
    "当定义一个新的类包含了前面类的特征时，就可以不用复制粘贴进行定义，可以直接“继承”，这样在进行修改时就只用修改一处，有效避免了一些需要调试的错误。\n",
    "\n",
    "比如先定义这样一个类,输入年龄、姓名、收入自动打印语句："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "351a0d4e",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Kartik earns 40000\n"
     ]
    }
   ],
   "source": [
    "class Person:\n",
    "    def __init__(self,name,age):\n",
    "        self.name = name\n",
    "        self.age = age\n",
    "    def salary(self, value):\n",
    "        self.money = value\n",
    "        print(self.name,\"earns\",self.money)\n",
    "\n",
    "a = Person('Kartik',26)\n",
    "a.salary(40000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "121788b7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['__class__',\n",
       " '__delattr__',\n",
       " '__dict__',\n",
       " '__dir__',\n",
       " '__doc__',\n",
       " '__eq__',\n",
       " '__format__',\n",
       " '__ge__',\n",
       " '__getattribute__',\n",
       " '__gt__',\n",
       " '__hash__',\n",
       " '__init__',\n",
       " '__init_subclass__',\n",
       " '__le__',\n",
       " '__lt__',\n",
       " '__module__',\n",
       " '__ne__',\n",
       " '__new__',\n",
       " '__reduce__',\n",
       " '__reduce_ex__',\n",
       " '__repr__',\n",
       " '__setattr__',\n",
       " '__sizeof__',\n",
       " '__str__',\n",
       " '__subclasshook__',\n",
       " '__weakref__',\n",
       " 'salary']"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dir(Person)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e9cecff9",
   "metadata": {},
   "source": [
    "现在我们定义一个新的类，和前面不同的是它还会打印职业，所以可以这么定义"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "ca88b496",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Artist(Person):#直接对Person类的功能进行继承\n",
    "    def artform(self, job):\n",
    "        self.job = job\n",
    "        print(self.name,\"is a\", self.job)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "81801665",
   "metadata": {},
   "source": [
    "可以看到，新的Artist类里面仍然包含了前面的salary方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "cf66fdbe",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['__class__',\n",
       " '__delattr__',\n",
       " '__dict__',\n",
       " '__dir__',\n",
       " '__doc__',\n",
       " '__eq__',\n",
       " '__format__',\n",
       " '__ge__',\n",
       " '__getattribute__',\n",
       " '__gt__',\n",
       " '__hash__',\n",
       " '__init__',\n",
       " '__init_subclass__',\n",
       " '__le__',\n",
       " '__lt__',\n",
       " '__module__',\n",
       " '__ne__',\n",
       " '__new__',\n",
       " '__reduce__',\n",
       " '__reduce_ex__',\n",
       " '__repr__',\n",
       " '__setattr__',\n",
       " '__sizeof__',\n",
       " '__str__',\n",
       " '__subclasshook__',\n",
       " '__weakref__',\n",
       " 'artform',\n",
       " 'salary']"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dir(Artist)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "528a9329",
   "metadata": {},
   "source": [
    "并且salary也可以直接在这个类中进行调用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "92814d31",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Nishanth earns 60000\n",
      "Nishanth is a Dancer\n"
     ]
    }
   ],
   "source": [
    "c = Artist('Nishanth',21)\n",
    "c.salary(60000)\n",
    "c.artform('Dancer')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "23cf6aa7",
   "metadata": {},
   "source": [
    "如果一个类包含多个方法，在继承时某一种方法不符合要求，可以在继承后重写"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6800bcc0",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Artist(Person):\n",
    "    def artform(self, job):\n",
    "        self.job = job\n",
    "        print(self.name,\"is a\", self.job)\n",
    "    def salary(self, value):\n",
    "        self.money = value\n",
    "        print(self.name,\"earns\",self.money)\n",
    "        print(\"I am overriding the SoftwareEngineer class's salary method\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d9bf25f8",
   "metadata": {},
   "source": [
    "和前面的函数输入一样，如果类的输入没有确定的个数，也可以前面加星号"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "eb5845b8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'IDoNotKnowWhatToType'"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class NotSure:\n",
    "    def __init__(self, *args):\n",
    "        self.data = ''.join(list(args)) \n",
    "yz = NotSure('I', 'Do' , 'Not', 'Know', 'What', 'To','Type')\n",
    "yz.data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "600a3c21",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[34, 10, 9, 9, 8, 5, 5, 4, 2, 2, 1, 0]\n"
     ]
    }
   ],
   "source": [
    "list=[1, 10, 4, 2, 9, 2, 34, 5, 9, 8, 5, 0]\n",
    "list.sort(reverse=True)\n",
    "print(list)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
